GEOS Technical Reference Notes

December, 1987

This document provides some preliminary information about the differences

between C64 GEOS and C128 GEOS. It is not intended to be comprehensive;

Compatibility with C64 GEOS software

------------------------------------

Most C64 GEOS software will run under the C128 GEOS in 40 column mode.

All data files, scraps, fonts, & printer drivers are identical under

C64 and C128 GEOS.

Input drivers are located at different addresses in the two machines, and

hence are incompatible. We have added a new file type, INPUT128, for C128

input drivers.

As the deskTop is heavily tied into each OS, we've decided to give the 128

it's own desktop filename, "128 DESKTOP", so as to avoid confusion with the 64's

"DESK TOP" file. (The deskTop is of file type "SYSTEM", and can't be renamed

by the user).

128 Flags for Applications & Desk Accessories

---------------------------------------------

In order for the 128 DESKTOP & other applications to know what files run in

what mode, we've adopted a standard that should be used on ALL applications,

desk accessories, & auto-execution programs. This flag is located in the

header block of each of these programs. Since permanent file names are only

16 bytes long, we have left over 4 bytes that have been unused till now, but

we've constantly been setting them to all 0's. The last of these bytes

(see OFF128FLAGS) now has meaning to the 128 OS & DeskTop:

B7 B6

0 0 runs under 128 GEOS, but in 40 column mode only

0 1 runs under 128 GEOS in 40 and 80 column modes

1 0 DOES NOT RUN under 128 GEOS (deskTop will display dialog box)

1 1 runs under 128 GEOS in 80 column mode only

Bits 5 through 0 are unused and should be 0. The 128 GEOS routines LdApplic

and LdDeskAcc will return the error #INCOMPATIBLE if these flags in the header

block do not allow running in the current mode.

Converting 64 GEOS software to run on the C128

----------------------------------------------

First, you need to decide whether your software is simply going to be able

to run in 40 col. mode, or whether it is to run in 40/80 column on the 128 only.

40 col. mode only on 128:

1) Chances are quite good your software already does.

2) If it doesn't, it's probably becuase you access BASIC -- the 128 has a

different BASIC, so you'll need to re-write that section of code to first see

which OS you're running under, & then use the appropriate BASIC variables &

jump entries.

40/80 col. on the C128 only:

1) Set the 128 flag as mentioned above in the save file to $40

2) In 80 column mode, you'll need to widen your menus to accomodate the wider

system font. We typically stuff these "right edge" values into the menu

structure itself based on the current graphicsMode

($80 is 80 column, $00 is 40)

3) Most of the graphic changes you'll need to make can be accomplished by

setting the high bit of every X position or width that you pass to the operating

system. The 128 GEOS will ignore this bit if in 40 column mode, and double the

value if in 80 column mode, thus automatically retaining the same sized image

on the screen. Hence, 50+$8000 is 50 pixels in 40 column mode and 100 pixels in

80 column mode.

4) If you're writing an application, add a "switch 40/80" option under the

geos menu. The action for this should be to EOR graphicsMode with $80,

store it back, and call the routine SetNewMode. You'll then need to redraw the

screen, now in the new graphics mode.

5) Nearly all x positions passed to the C128 GEOS can have the high bit set

causing the position to automatically be doubled in 80 column mode. It has

been noted that this always results in the low bit of the resulting word being

a 0. This can make life difficult, if you desire to fill a pattern to the

right edge of the screen, for instance. To solve this problem, I've modified

the normalization routine: The 15th bit of the word continues to be the same

"double me if 80 col." flag, but the 14th bit now has significance in 80 col.

mode only -- it becomes the low bit of the doubled word. So, if you want the

right edge of the screen, use the value $C000+319.

Sprites

-------

The C64 contains a chip to handle sprites in hardware. Unfortunately, this chip

is not available on the 128, so the functions of that chip have been simulated

in software that is included in the 128 kernal. Most of the capabilities of

the VIC chip have been taken care of, and if you are not doing exotic things

with sprites your code may work with one or two changes.

The major changes include: sprite 0 (the cursor) is treated differently than

any other sprite. The code for this beast has been optimized to get reasonably

fast mouse response, with a resulting loss in functionality. You cannot double

the cursor's size in either x or y. You cannot change the color of the cursor.

The size of the cursor is limited to 16-pixels wide and 8 lines high. One

added feature is the ability to add a white outline to the picture that is used

for the cursor. This allows it to be seen while moving over a black

background.

For the other 7 sprites, all the capabilities have been emulated except for

color and collision detection. In addition, the 64th byte of the sprite

picture definition (previously unused) is now used to provide some size info

about the sprite. This is used to optimize the drawing code. Here are some

problem areas to watch out for:

Writing directly to the screen:

Since the old sprite were handled with hardware, writing to the screen wasn't

a problem. If you do it (system calls NOT included), then call "TempHideMouse"

before the write. This will erase the cursor and any sprites you have enabled.

You don't have to do anything to get them back, this is done automatically

during the next main loop.

All sprite picture data:

All picture data should be adjusted to include the 64th byte. This byte has

size information that is read by the software sprite routines, even if they

are garbage values. The format of this byte is: high bit set means that the

sprite is no more that 9 pixels wide (this means it can be shifted 7 times

and still be contained in 2 bytes). The rest of the byte is a count of the

scan lines in the sprite. You can either include this info as part of the

picture definition, or stuff it into the right place with some special code.

Writing directly to the VIC chip:

This is generally ok, since the sprite emulation routines take the position

and doubling info from the registers on the VIC chip, with the exception of the

x position. The VIC chip allows 9 bits for x positions, which is not enough

640-wide screen. You should write the x position to the global variables

"reqXpos0, reqXpos1..." (request x pos). These are full words, in consecutive

locations. Better yet, use the "PosSprite" call in the kernel.

Reading values from the VIC chip:

This is also ok for the status values and for the y position. The x position

can be useful also, if you use the PosSprite call. In addition to filling

the global variables reqXpos0, etc., this call divides the x position by two

and stuffs it into the VIC chip.

Using VIC chip collision detection:

This is iffy. The chip continues to operate, so if you are using the

PosSprite call (see above) collisions should be detected with some loss of

accuracy (the low bit). This has not been tested, so if you try it -- report

the results here.

Writing to the VIC chip (or calling PosSprite, EnablSprite, DisablSprite)

at interrupt level:

Don't do it. Since the mouse and the sprites are drawn at main loop, this

causes subtle, irreproducable timing bugs that are impossible to get out.

Known bugs in release 1 of GEOS 128

-----------------------------------

1) If location $1300 in application space is zero, then sprites in 80 column

mode go haywire. All of our current applications that run in 80 column

mode have put in a patch for this. Bug is in sprite code.

2) Doubling bitmaps through BitmapClip doesn't work.

3) iBitmapClip needs call to TempHideMouse before being called.

;**************************************************************************

;This file contains additional memory map definitions for applications which

;will run under the GEOS 128 kernal. 12/11/87.

;**************************************************************************

;Memory-management unit in C-128

mmu= $D500

VDC= $D600

;Address of memory-map configuration register in C-128

config= $FF00

;Misc addresses:

keyreg= $d02f;C-128 keyboard register for # pad & other keys

clkreg= $d030;C-128 clock speed register

;Address of input driver

MOUSEBASE= $FD00

ENDMOUSE= $FE80

;Note that the jump table entries for input driver routines have not moved;

;They are still at MOUSEJMP ($FE80). In 128 GEOS, there is one additional

;vector:

SetMouse= MOUSEJMP+9;($FE89)

;Jump addresses within disk drivers -- these are only valid for non-1541

;disk drive types, and for the 128 version of the 1541 driver:

Get1stDirEntry= $9030;returns first dir entry

GetNxtDirEntry= $9033;returns next dir entry

AllocateBlock= $9048;allocates specific block

ReadLink= $904B;like ReadBlock, but returns only 1st two bytes

;The following address holds info about the current 128 graphics mode:

;$00 for VIC, $80 for VDC 640*200, and $C0 for VDC 640*400 (not yet supported).

graphicsMode= $003f;holds current 128 graphics mode

;Misc vectors:

JmpIndX= $9D80;address of routine used by 128 kernal

;-----------------------------------------------------------------------------

;This is a second GLOBAL memory area for GEOS. It is here so that these

;variables may be in the same place in V1.3 as they are running V1.2 with

;the V1.3 deskTop. This allows other input drivers to be auto-booted by

;those who have a V1.2 GEOS KERNAL, but have gotten the V1.3 deskTop via

;a download or up-grade disk. They are EQUATED to be past the local GEOS

;variables, in fact at the end of the GEOS RAM space. Here they must

;permanently reside, for the sake of compatibility.

;Saved value of moby2 for context saving done in dlg boxes & desk accessories.

;Left out of original GEOS save code, put here so we don't screw up desk

;accessories, etc, that know the size of TOTSRAMSAVED above.

savedmoby2= $88bb

;copy of reg 24 in VDC for C128

screen80polarity= $88bc

;Screen colors for 80 column mode on C128. Copy of reg 26 in VDC

screen80colors= $88bd

;Holds current color mode for C128 color routines.

vdcClrMode= $88be

;(4 bytes) 1 byte each reserved for disk drivers about each device

;(each driver may use differently)

driveData= $88bf

;Number of 64K ram banks available in Ram Expansion Unit. 0 if none available.

ramExpSize= $88c3

;If RAM expansion is in, Bank 0 is reserved for the kernal's use. This byte

;contains flags designating its usage:

;

; Bit 7: if 1, $0000-$78FF used by MoveData routine

; Bit 6: if 1, $8300-$B8FF holds disk drivers for drives A through C

; Bit 5: if 1, $7900-$7DFF is loaded with GEOS ram area $8400-$88FF by ToBasic

;routine when going to BASIC

; Bit 4: if 1, $7E00-$82FF is loaded with reboot code by a setup AUTO-EXEC

;file, which is loaded by the restart code in GEOS at $C000 if

;this flag is set, at $6000, instead of loading GEOSBOOT.

;Also, in the area $B900-$FC3F is saved the kernal for fast

;re-boot without system disk (depending on setup file).

;This area should be updated when input devices are changed

;(implemented in V1.3 deskTop)

sysRAMFlg= $88c4

;This flag is changed from 0 to $FF after deskTop comes up for the first time

;after booting.

firstBoot= $88c5

;(4 bytes) Current disk type for each drive (copied from diskType)

curType= $88c6

;(4 bytes) RAM bank for each disk drive to use if drive type is RAM DISK

;or Shadowed Drive

ramBase= $88c7

;(17 bytes) Holds name of current input device

inputDevName= $88cb

;(18 bytes) Disk name of disk in drive C. (Padded with $a0)

DrCCurDkNm= $88dc

;(18 bytes) Disk name of disk in drive D. (Padded with $a0)

DrDCurDkNm= $88ee

;(256 bytes) 2nd directory header block, for larger disk capacity drives

;(such as 1571)

dir2Head= $8900

;-----------------------------------------------------------------------------

;**************************************************************************

;This file contains additional jump-table entries for applications which

;will run under the GEOS 128 kernal. 12/11/87.

;**************************************************************************

TempHideMouse= $c2d7

SetMousePicture= $c2da

SetNewMode= $c2dd

NormalizeX= $c2e0

MoveBData= $c2e3

SwapBData= $c2e6

VerifyBData= $c2e9

DoBOp= $c2ec

AccessCache= $c2ef

HideOnlyMouse= $c2f2

SetColorMode= $c2f5

ColorCard= $c2f8

ColorRectangle= $c2fb

;**************************************************************************

;This file contains additional constant definitions for applications which

;will run under the GEOS 128 kernal. 12/11/87

;**************************************************************************

;The following equates define the numbers written to the "config"

;register (location $FF00 in C-128). This register controls the memory map

;of the C-128.

CIOIN= $7E;60K RAM, 4K I/O space in

CRAM64K= $7F;64K RAM

CKRNLBASIOIN= $40;kernal, I/O and basic ROM's mapped into memory

CKRNLIOIN= $4E;Kernal ROM and I/O space mapped in

;Keyboard equates

KEYHELP= 25

KEYALT= 26

KEYESC= 27

KEYNOSCRL= 7

KEYENTER= 11

;128 screen size constants

SCREENBYTEWIDTH= 80

SCREENPIXELWIDTH= 640

;New GEOS file types:

INPUT128= 15;128 Input driver

;New # of file types, including NONGEOS (=0)

NUMFILETYPES= 16

;The following equate can be used as an offset into a file's header block.

;It points to the byte which contains flags which indicate if the program

;will run under C-128 GEOS in 40 and/or 80 column modes. These flags are valid

;for applications, desk accessories, and auto-exec files.

;

;B7 B6

; 0 0 runs under 128 GEOS, but in 40 column mode only

; 0 1 runs under 128 GEOS in 40 and 80 column modes

; 1 0 DOES NOT RUN under 128 GEOS (deskTop will display dialog box)

; 1 1 runs under 128 GEOS in 80 column mode only

OFF128FLAGS= 96

;disk equates

DIR1581TRACK= 40;track # reserved on 1581 disk for directory